﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using RotovapPlatform.Domain.Business.Interfaces;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Business.Recipes.Entities.Parameters;
using static RotovapPlatform.Domain.Business.Recipe.Enums.RecipeEnums;
using RotovapPlatform.Application.Services;
using System.Diagnostics;
using RotovapPlatform.UI.Services;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
using System.Timers;
using RotovapPlatform.Domain.Recipes.Services;
using RotovapPlatform.Domain.Business.Storage.Entities.Bottles;
using RotovapPlatform.Domain.Business.Storage.Enums;
using RotovapPlatform.Application.Services.Storages;
using RotovapPlatform.Domain.Services.DeviceParameters;

namespace RotovapPlatform.UI.ViewModels.RecipeManagement
{
	/// <summary>
	/// 配方编辑器视图模型
	/// </summary>
	[ObservableObject]
	public partial class RecipeEditorViewModel
	{
		private readonly IRecipeAppService _recipeAppService;
		private readonly ILogger<RecipeEditorViewModel> _logger;
		private readonly IMessageService _messageService;
		private readonly IStorageAppService _storageAppService;
		private readonly IDeviceParameterDomainService _deviceParameterService;


		public RecipeEditorViewModel(IRecipeAppService recipeAppService, ILogger<RecipeEditorViewModel> logger, IMessageService messageService, IStorageAppService storageAppService, IDeviceParameterDomainService deviceParameterService)
		{
			_recipeAppService = recipeAppService;
			_logger = logger;
			_messageService = messageService;
			_storageAppService = storageAppService;
			_deviceParameterService = deviceParameterService;
			Recipes = new ObservableCollection<RecipeDefinition>();
			ExperimentGroups = new ObservableCollection<ExperimentGroup>();
			InitializeEditingRecipe();
			AvailableRotovapMaterials = new ObservableCollection<string>();
			AvailableCleaningSolutions = new ObservableCollection<string>();
			MatchedBottleLocations = new ObservableCollection<BottleLocationViewModel>();
		}

		#region 字段

		/// <summary>
		/// 每页显示的配方数量选项
		/// </summary>
		private readonly int[] _pageSizes = { 2, 3, 4, 10, 20 };

		/// <summary>
		/// 所有配方列表
		/// </summary>
		private ObservableCollection<RecipeDefinition> _allRecipes;

		/// <summary>
		/// 当前页码
		/// </summary>
		private int _currentPage = 1;

		/// <summary>
		/// 搜索文本
		/// </summary>
		private string _searchText;

		/// <summary>
		/// 选中的每页显示数量
		/// </summary>
		private int _selectedPageSize = 2;

		/// <summary>
		/// 是否正在加载
		/// </summary>
		private bool _isLoading;

		/// <summary>
		/// 是否已初始化
		/// </summary>
		private bool _isInitialized;

		/// <summary>
		/// 总页数
		/// </summary>
		private int _totalPages = 1;

		/// <summary>
		/// 选中的配方
		/// </summary>
		private RecipeDefinition _selectedRecipe;

		/// <summary>
		/// 正在编辑的配方
		/// </summary>
		private RecipeDefinition _editingRecipe;

		[ObservableProperty]
		private ExperimentGroup _selectedExperimentGroup;

		[ObservableProperty]
		private ObservableCollection<ExperimentGroup> _experimentGroups = new();

		[ObservableProperty]
		private string _newGroupName;

		[ObservableProperty]
		private string _displayGroupName;

		// 添加一个标志来控制是否是用户手动选择
		private bool _isUserSelection = true;

		#endregion

		#region 属性

		/// <summary>
		/// 所有配方列表
		/// </summary>
		public ObservableCollection<RecipeDefinition> Recipes
		{
			get => _allRecipes;
			set => SetProperty(ref _allRecipes, value);
		}

		/// <summary>
		/// 当前页显示的配方列表
		/// </summary>
		public ObservableCollection<RecipeDefinition> PagedRecipes { get; } = new();

		/// <summary>
		/// 每页显示数量选项
		/// </summary>
		public int[] PageSizes => _pageSizes;

		/// <summary>
		/// 选中的每页显示数量
		/// </summary>
		public int SelectedPageSize
		{
			get => _selectedPageSize;
			set
			{
				if (SetProperty(ref _selectedPageSize, value))
				{
					CurrentPage = 1; // 重置到第一页
					UpdatePagedRecipes();
					UpdatePaginationCommands();
				}
			}
		}

		/// <summary>
		/// 当前页码
		/// </summary>
		public int CurrentPage
		{
			get => _currentPage;
			set
			{
				if (SetProperty(ref _currentPage, value))
				{
					UpdatePagedRecipes();
					UpdatePaginationCommands();
				}
			}
		}

		/// <summary>
		/// 搜索文本
		/// </summary>
		public string SearchText
		{
			get => _searchText;
			set
			{
				if (SetProperty(ref _searchText, value))
				{
					CurrentPage = 1; // 重置到第一页
					UpdatePagedRecipes();
					UpdatePaginationCommands();
				}
			}
		}

		/// <summary>
		/// 选中的配方
		/// </summary>
		public RecipeDefinition SelectedRecipe
		{
			get => _selectedRecipe;
			set
			{
				if (SetProperty(ref _selectedRecipe, value))
				{
					// 只有在明确选择配方时才更新编辑区
					if (value != null && _isUserSelection)
					{
						// 创建配方的深拷贝
						EditingRecipe = new RecipeDefinition
						{
							ExperimentName = value.ExperimentName,
							ExperimentDescription = value.ExperimentDescription,
							CreatedTime = value.CreatedTime,
							Operator = value.Operator,
							ExperimentType = value.ExperimentType,
							RotovapParameters = value.RotovapParameters?.Clone() ?? new RotovapParameters
							{
								ProductParameters = new ObservableCollection<ProductParameters>(),
								MaterialLocations = new ObservableCollection<int>(),
								ResidualLiquidParameters = new ResidualLiquidParameters(),
								CleaningParameters = new CleaningParameters()
							}
						};
					}

					OnPropertyChanged(nameof(CanAddProductParameters));
				}
			}
		}

		/// <summary>
		/// 正在编辑的配方
		/// </summary>
		public RecipeDefinition EditingRecipe
		{
			get => _editingRecipe;
			set
			{
				if (SetProperty(ref _editingRecipe, value))
				{
					OnEditingRecipeChanged(value);
				}
			}
		}

		/// <summary>
		/// 清洗溶剂列表
		/// </summary>
		public List<string> CleaningSolvents { get; } = new()
	{
		"乙醇",
		"丙酮",
		"二氯甲烷",
		"正己烷"
	};

		/// <summary>
		/// 是否可以添加产物参数组
		/// </summary>
		public bool CanAddProductParameters =>
			EditingRecipe?.RotovapParameters?.ProductParameters?.Count < 3;

		/// <summary>
		/// 是否正在加载
		/// </summary>
		public bool IsLoading
		{
			get => _isLoading;
			set => SetProperty(ref _isLoading, value);
		}

		/// <summary>
		/// 总页数
		/// </summary>
		public int TotalPages
		{
			get => _totalPages;
			private set => SetProperty(ref _totalPages, value);
		}

		/// <summary>
		/// 可用的旋蒸物料列表
		/// </summary>
		[ObservableProperty]
		private ObservableCollection<string> _availableRotovapMaterials;

		/// <summary>
		/// 可用的清洗液列表
		/// </summary>
		[ObservableProperty]
		private ObservableCollection<string> _availableCleaningSolutions;

		/// <summary>
		/// 匹配当前选择物料的瓶子位置列表
		/// </summary>
		[ObservableProperty]
		private ObservableCollection<BottleLocationViewModel> _matchedBottleLocations;

		#region 参数范围属性

		/// <summary>
		/// 油浴温度最小值
		/// </summary>
		public double OilTemperatureMin { get; private set; }

		/// <summary>
		/// 油浴温度最大值
		/// </summary>
		public double OilTemperatureMax { get; private set; }

		/// <summary>
		/// 油浴温度单位
		/// </summary>
		public string OilTemperatureUnit { get; private set; }

		/// <summary>
		/// 旋蒸转速最小值
		/// </summary>
		public double RotarySpeedMin { get; private set; }

		/// <summary>
		/// 旋蒸转速最大值
		/// </summary>
		public double RotarySpeedMax { get; private set; }

		/// <summary>
		/// 旋蒸转速单位
		/// </summary>
		public string RotarySpeedUnit { get; private set; }

		/// <summary>
		/// 阶梯温度最小值
		/// </summary>
		public double StepTemperatureMin { get; private set; }

		/// <summary>
		/// 阶梯温度最大值
		/// </summary>
		public double StepTemperatureMax { get; private set; }

		/// <summary>
		/// 阶梯温度单位
		/// </summary>
		public string StepTemperatureUnit { get; private set; }

		/// <summary>
		/// 阶梯稳定时间最小值
		/// </summary>
		public double StepStableTimeMin { get; private set; }

		/// <summary>
		/// 阶梯稳定时间最大值
		/// </summary>
		public double StepStableTimeMax { get; private set; }

		/// <summary>
		/// 阶梯稳定时间单位
		/// </summary>
		public string StepStableTimeUnit { get; private set; }

		/// <summary>
		/// 旋蒸时间最小值
		/// </summary>
		public double RotaryTimeMin { get; private set; }

		/// <summary>
		/// 旋蒸时间最大值
		/// </summary>
		public double RotaryTimeMax { get; private set; }

		/// <summary>
		/// 旋蒸时间单位
		/// </summary>
		public string RotaryTimeUnit { get; private set; }

		/// <summary>
		/// 冷凝温度最小值
		/// </summary>
		public double CondensationTemperatureMin { get; private set; }

		/// <summary>
		/// 冷凝温度最大值
		/// </summary>
		public double CondensationTemperatureMax { get; private set; }

		/// <summary>
		/// 冷凝温度单位
		/// </summary>
		public string CondensationTemperatureUnit { get; private set; }

		/// <summary>
		/// 真空度最小值
		/// </summary>
		public double VacuumMin { get; private set; }

		/// <summary>
		/// 真空度最大值
		/// </summary>
		public double VacuumMax { get; private set; }

		/// <summary>
		/// 真空度单位
		/// </summary>
		public string VacuumUnit { get; private set; }

		/// <summary>
		/// 清洗体积最小值
		/// </summary>
		public double CleaningVolumeMin { get; private set; }

		/// <summary>
		/// 清洗体积最大值
		/// </summary>
		public double CleaningVolumeMax { get; private set; }

		/// <summary>
		/// 清洗体积单位
		/// </summary>
		public string CleaningVolumeUnit { get; private set; }

		/// <summary>
		/// 清洗速度最小值
		/// </summary>
		public double CleaningSpeedMin { get; private set; }

		/// <summary>
		/// 清洗速度最大值
		/// </summary>
		public double CleaningSpeedMax { get; private set; }

		/// <summary>
		/// 清洗速度单位
		/// </summary>
		public string CleaningSpeedUnit { get; private set; }

		/// <summary>
		/// 清洗时间最小值
		/// </summary>
		public double CleaningTimeMin { get; private set; }

		/// <summary>
		/// 清洗时间最大值
		/// </summary>
		public double CleaningTimeMax { get; private set; }

		/// <summary>
		/// 清洗时间单位
		/// </summary>
		public string CleaningTimeUnit { get; private set; }

		#endregion

		#endregion

		#region 命令

		/// <summary>
		/// 上一页命令
		/// </summary>
		[RelayCommand]
		private void PreviousPage()
		{
			if (CurrentPage > 1)
			{
				CurrentPage--;
				UpdatePaginationCommands();
			}
		}

		/// <summary>
		/// 下一页命令
		/// </summary>
		[RelayCommand]
		private void NextPage()
		{
			if (CurrentPage < _totalPages)
			{
				CurrentPage++;
				UpdatePaginationCommands();
			}
		}

		/// <summary>
		/// 添加瓶子命令
		/// </summary>
		[RelayCommand]
		private void AddBottle()
		{
			if (EditingRecipe == null)
			{
				EditingRecipe = new RecipeDefinition
				{
					RotovapParameters = new RotovapParameters
					{
						MaterialLocations = new ObservableCollection<int>()
					}
				};
			}
			else if (EditingRecipe.RotovapParameters == null)
			{
				EditingRecipe.RotovapParameters = new RotovapParameters
				{
					MaterialLocations = new ObservableCollection<int>()
				};
			}
			else if (EditingRecipe.RotovapParameters.MaterialLocations == null)
			{
				EditingRecipe.RotovapParameters.MaterialLocations = new ObservableCollection<int>();
			}

			EditingRecipe.RotovapParameters.MaterialLocations.Add(0);

			// 通知UI更新
			OnPropertyChanged(nameof(EditingRecipe));
		}

		/// <summary>
		/// 添加产物参数组命令
		/// </summary>
		[RelayCommand]
		private void AddProductParameters()
		{
			if (EditingRecipe == null)
			{
				_logger.LogWarning("无法添加产物参数：EditingRecipe 为空");
				return;
			}

			if (EditingRecipe.RotovapParameters == null)
			{
				_logger.LogInformation("初始化 RotovapParameters");
				EditingRecipe.RotovapParameters = new RotovapParameters
				{
					ProductParameters = new ObservableCollection<ProductParameters>()
				};
			}
			else if (EditingRecipe.RotovapParameters.ProductParameters == null)
			{
				_logger.LogInformation("初始化 ProductParameters 集合");
				EditingRecipe.RotovapParameters.ProductParameters = new ObservableCollection<ProductParameters>();
			}

			if (EditingRecipe.RotovapParameters.ProductParameters.Count < 3)
			{
				_logger.LogInformation("添加新的产物参数组");

				// 使用设备参数服务中的默认值
				var newParams = new ProductParameters
				{
					OilTemperature = (OilTemperatureMin + OilTemperatureMax) / 2,
					RotarySpeed = (RotarySpeedMin + RotarySpeedMax) / 2,
					RotaryTime = (RotaryTimeMin + RotaryTimeMax) / 2,
					CondensationTemperature = (CondensationTemperatureMin + CondensationTemperatureMax) / 2,
					Vacuum = (VacuumMin + VacuumMax) / 2,
					StepTemperature = (StepTemperatureMin + StepTemperatureMax) / 2,
					StepStableTime = (StepStableTimeMin + StepStableTimeMax) / 2,
					IsStepTemperature = false,
					IsSmartTemperatureJudgment = false,
					IsCondensationCollect = false,
					IsSampling = false
				};

				_logger.LogDebug($"新建产物参数：油浴温度={newParams.OilTemperature}, 转速={newParams.RotarySpeed}, 时间={newParams.RotaryTime}");

				EditingRecipe.RotovapParameters.ProductParameters.Add(newParams);
				OnPropertyChanged(nameof(CanAddProductParameters));

				// 触发 EditingRecipe 属性变更通知，确保 UI 更新
				OnPropertyChanged(nameof(EditingRecipe));
			}
		}

		/// <summary>
		/// 删除产物参数组命令
		/// </summary>
		[RelayCommand]
		private void DeleteProductParameters(ProductParameters parameters)
		{
			if (EditingRecipe?.RotovapParameters?.ProductParameters == null)
			{
				return;
			}

			EditingRecipe.RotovapParameters.ProductParameters.Remove(parameters);
			OnPropertyChanged(nameof(CanAddProductParameters));
		}

		/// <summary>
		/// 删除瓶子命令
		/// </summary>
		[RelayCommand]
		private void RemoveBottle(BottleLocationViewModel bottleLocation)
		{
			if (bottleLocation != null && EditingRecipe?.RotovapParameters != null)
			{
				// 从匹配位置列表中移除
				MatchedBottleLocations.Remove(bottleLocation);

				// 从MaterialLocations中移除对应位置
				EditingRecipe.RotovapParameters.MaterialLocations.Remove(bottleLocation.Position);

				// 触发属性变更通知，确保UI更新
				OnPropertyChanged(nameof(MatchedBottleLocations));
			}
		}

		/// <summary>
		/// 保存配方命令
		/// </summary>
		[RelayCommand]
		private async Task SaveRecipeAsync()
		{
			if (EditingRecipe == null)
			{
				await _messageService.ShowErrorAsync("无效的配方数据");
				return;
			}

			try
			{
				_logger.LogDebug($"准备保存配方，ExperimentName: {EditingRecipe.ExperimentName}");

				IsLoading = true;

				// 保存原有的配方数据
				var recipeToSave = new RecipeDefinition
				{
					RecipeId = Guid.NewGuid(),
					ExperimentName = EditingRecipe.ExperimentName,
					ExperimentDescription = EditingRecipe.ExperimentDescription,
					CreatedTime = DateTime.Now,
					Operator = EditingRecipe.Operator,
					ExperimentType = ExperimentType.RotaryEvaporation,
					RotovapParameters = EditingRecipe.RotovapParameters?.Clone()
				};

				// 使用应用服务验证配方
				var (isValid, errorMessage) = await _recipeAppService.ValidateRecipeAsync(recipeToSave);
				if (!isValid)
				{
					throw new InvalidOperationException(errorMessage);
				}

				// 保存配方
				var result = await _recipeAppService.CreateRecipeAsync(recipeToSave);
				if (!result.Success)
				{
					throw new InvalidOperationException(result.Message);
				}

				_logger.LogInformation($"配方 {recipeToSave.ExperimentName} 保存成功");
				await _messageService.ShowInfoAsync("配方保存成功");

				// 仅刷新配方列表，不清空编辑区
				await LoadRecipesAsync();
			}
			catch (DbUpdateException dbEx)
			{
				_logger.LogError($"数据库更新错误: {dbEx.Message}");
				_logger.LogError($"内部异常: {dbEx.InnerException?.Message}");
				await _messageService.ShowErrorAsync($"保存配方失败: {dbEx.InnerException?.Message ?? dbEx.Message}");
			}
			catch (InvalidOperationException ex)
			{
				_logger.LogError($"配方验证失败: {ex.Message}");
				await _messageService.ShowErrorAsync($"配方验证失败: {ex.Message}");
			}
			catch (Exception ex)
			{
				_logger.LogError($"保存配方失败: {ex.Message}");
				await _messageService.ShowErrorAsync($"保存配方失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 保存配方并添加到实验组
		/// </summary>
		[RelayCommand]
		private async Task SaveAndAddToGroupAsync()
		{
			try
			{
				if (EditingRecipe == null)
				{
					await _messageService.ShowErrorAsync("请先创建或选择一个配方");
					return;
				}

				if (string.IsNullOrWhiteSpace(DisplayGroupName))
				{
					await _messageService.ShowErrorAsync("请输入实验组名称");
					return;
				}

				IsLoading = true;

				// 创建一个新的配方对象，确保使用新的RecipeId
				var recipeToSave = new RecipeDefinition
				{
					RecipeId = Guid.NewGuid(),
					ExperimentName = EditingRecipe.ExperimentName,
					ExperimentDescription = EditingRecipe.ExperimentDescription,
					CreatedTime = DateTime.Now,
					Operator = EditingRecipe.Operator,
					ExperimentType = ExperimentType.RotaryEvaporation,
					RotovapParameters = EditingRecipe.RotovapParameters?.Clone()
				};

				// 使用应用服务验证配方
				var (isValid, errorMessage) = await _recipeAppService.ValidateRecipeAsync(recipeToSave);
				if (!isValid)
				{
					throw new InvalidOperationException(errorMessage);
				}

				// 保存配方
				var saveResult = await _recipeAppService.CreateRecipeAsync(recipeToSave);
				if (!saveResult.Success)
				{
					await _messageService.ShowErrorAsync($"保存配方失败: {saveResult.Message}");
					return;
				}

				// 获取保存后的配方ID
				var recipeId = saveResult.RecipeId.Value;

				// 获取完整的配方对象
				var savedRecipe = await _recipeAppService.GetRecipeByIdAsync(recipeId);
				if (savedRecipe == null)
				{
					await _messageService.ShowErrorAsync("无法获取保存的配方");
					return;
				}

				// 检查是否需要创建新的实验组
				ExperimentGroup targetGroup;
				if (SelectedExperimentGroup == null)
				{
					// 创建新的实验组
					var newGroup = new ExperimentGroup
					{
						GroupId = Guid.NewGuid(),
						GroupName = DisplayGroupName,
						CreatedTime = DateTime.Now,
						Creator = "当前用户",
						Description = "通过保存配方创建的实验组",
						Recipes = new ObservableCollection<RecipeDefinition> { savedRecipe },
						Experiments = new ObservableCollection<Experiment>(),
						Status = ExperimentGroupStatus.Pending,
						ErrorMessage = string.Empty,
						ExecutionProgress = 0,
						Executor = "当前用户"
					};

					// 从配方创建实验
					newGroup.CreateExperimentsFromRecipes();

					var createResult = await _recipeAppService.CreateExperimentGroupAsync(newGroup);
					if (!createResult.Success)
					{
						await _messageService.ShowErrorAsync($"创建实验组失败: {createResult.Message}");
						return;
					}

					targetGroup = newGroup;
					await _messageService.ShowInfoAsync("已创建新实验组并添加配方");
				}
				else
				{
					// 使用现有实验组
					targetGroup = SelectedExperimentGroup;

					// 检查配方是否已在实验组中
					if (targetGroup.Recipes.Any(r => r.RecipeId == recipeId))
					{
						await _messageService.ShowWarningAsync("该配方已在实验组中");
					}
					else
					{
						// 添加配方到现有实验组
						var addResult = await _recipeAppService.AddRecipeToGroupAsync(targetGroup.GroupId, recipeId);
						if (!addResult.Success)
						{
							await _messageService.ShowErrorAsync($"添加配方到实验组失败: {addResult.Message}");
							return;
						}

						// 获取更新后的实验组
						var updatedGroups = await _recipeAppService.GetAllExperimentGroupsAsync();
						var updatedGroup = updatedGroups.FirstOrDefault(g => g.GroupId == targetGroup.GroupId);

						if (updatedGroup != null)
						{
							// 更新实验列表
							updatedGroup.CreateExperimentsFromRecipes();

							// 更新实验组
							await _recipeAppService.UpdateExperimentGroupAsync(updatedGroup);
							targetGroup = updatedGroup;
						}

						await _messageService.ShowInfoAsync("配方已添加到实验组");
					}
				}

				// 重新加载实验组列表
				await LoadExperimentGroupsAsync();

				// 选择目标实验组
				SelectedExperimentGroup = ExperimentGroups.FirstOrDefault(g => g.GroupId == targetGroup.GroupId);

				// 重置编辑区域
				ResetEditingRecipe();

				// 刷新配方列表
				await LoadRecipesAsync();
			}
			catch (InvalidOperationException ex)
			{
				await _messageService.ShowErrorAsync($"配方验证失败: {ex.Message}");
				_logger.LogError($"配方验证失败: {ex.Message}");
			}
			catch (Exception ex)
			{
				await _messageService.ShowErrorAsync($"操作失败: {ex.Message}");
				_logger.LogError($"保存配方并添加到实验组时发生错误: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 删除配方命令
		/// </summary>
		[RelayCommand]
		private async Task DeleteRecipeAsync(RecipeDefinition recipe)
		{
			if (recipe == null) return;

			try
			{
				var confirm = await _messageService.ShowConfirmAsync($"确定要删除配方 {recipe.ExperimentName} 吗？", "删除确认");
				if (!confirm) return;

				IsLoading = true;
				var result = await _recipeAppService.DeleteRecipeAsync(recipe.RecipeId);

				if (result.Success)
				{
					_logger.LogInformation($"配方 {recipe.ExperimentName} 删除成功");
					await _messageService.ShowInfoAsync("配方删除成功");
					await LoadRecipesAsync();
					ResetEditingRecipe();
				}
				else
				{
					_logger.LogWarning($"删除配方失败: {result.Message}");
					await _messageService.ShowErrorAsync($"删除失败: {result.Message}");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"删除配方时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"删除失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 重置编辑区域
		/// </summary>
		private void ResetEditingRecipe()
		{
			InitializeEditingRecipe();
		}

		/// <summary>
		/// 添加配方到实验组
		/// </summary>
		[RelayCommand]
		private async Task AddRecipeToGroupAsync(RecipeDefinition recipe)
		{
			if (recipe == null)
			{
				await _messageService.ShowErrorAsync("请先选择配方");
				return;
			}

			if (string.IsNullOrWhiteSpace(DisplayGroupName))
			{
				await _messageService.ShowErrorAsync("请先输入实验组名称");
				return;
			}

			try
			{
				IsLoading = true;

				// 验证配方
				_logger.LogInformation($"正在验证配方 '{recipe.ExperimentName}' 是否有效...");
				var (isValid, errorMessage) = await _recipeAppService.ValidateRecipeAsync(recipe);
				if (!isValid) //直接验证失败
				{
					throw new InvalidOperationException(errorMessage);
				}

				Guid? targetGroupId = null;

				if (SelectedExperimentGroup == null)
				{
					// 创建新的实验组
					var newGroup = new ExperimentGroup
					{
						GroupId = Guid.NewGuid(),
						GroupName = DisplayGroupName,
						CreatedTime = DateTime.Now,
						Creator = "当前用户",
						Description = "自动创建的实验组",
						Recipes = new ObservableCollection<RecipeDefinition> { recipe },
						Experiments = new ObservableCollection<Experiment>(),
						Status = ExperimentGroupStatus.Pending,
						ErrorMessage = string.Empty,
						ExecutionProgress = 0,
						Executor = "当前用户"
					};

					// 从配方创建实验
					newGroup.CreateExperimentsFromRecipes();

					var createResult = await _recipeAppService.CreateExperimentGroupAsync(newGroup);
					if (!createResult.Success)
					{
						await _messageService.ShowErrorAsync($"创建新实验组失败: {createResult.Message}");
						return;
					}

					targetGroupId = createResult.GroupId;
					await _messageService.ShowInfoAsync("已创建新实验组并添加配方");
				}
				else if (SelectedExperimentGroup != null)
				{
					// 检查配方是否已在实验组中
					if (SelectedExperimentGroup.Recipes.Any(r => r.RecipeId == recipe.RecipeId))
					{
						await _messageService.ShowWarningAsync("该配方已在实验组中");
						return;
					}

					targetGroupId = SelectedExperimentGroup.GroupId;

					// 添加配方到现有实验组
					var result = await _recipeAppService.AddRecipeToGroupAsync(targetGroupId.Value, recipe.RecipeId);
					if (!result.Success)
					{
						await _messageService.ShowErrorAsync($"添加配方到实验组失败: {result.Message}");
						return;
					}

					// 获取更新后的实验组
					var updatedGroups = await _recipeAppService.GetAllExperimentGroupsAsync();
					var updatedGroup = updatedGroups.FirstOrDefault(g => g.GroupId == targetGroupId.Value);

					if (updatedGroup != null)
					{
						// 更新实验列表
						updatedGroup.CreateExperimentsFromRecipes();

						// 更新实验组
						await _recipeAppService.UpdateExperimentGroupAsync(updatedGroup);
					}

					await _messageService.ShowInfoAsync("配方已成功添加到实验组");
				}
				else
				{
					await _messageService.ShowErrorAsync("请先选择或创建一个实验组");
					return;
				}

				// 保存当前选中的实验组ID
				var currentGroupId = targetGroupId;

				// 重新加载实验组列表
				var groups = await _recipeAppService.GetAllExperimentGroupsAsync();

				// 更新集合而不是创建新的集合
				ExperimentGroups.Clear();
				foreach (var group in groups)
				{
					ExperimentGroups.Add(group);
				}

				// 重新选择之前的实验组
				if (currentGroupId.HasValue)
				{
					SelectedExperimentGroup = ExperimentGroups.FirstOrDefault(g => g.GroupId == currentGroupId);
				}
			}
			catch (Exception ex)
			{
				await _messageService.ShowErrorAsync($"操作失败: {ex.Message}");
				_logger.LogError($"添加配方到实验组时发生错误: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 从实验组中移除配方命令
		/// </summary>
		[RelayCommand]
		private async Task RemoveRecipeFromGroupAsync(RecipeDefinition recipe)
		{
			if (recipe == null)
			{
				await _messageService.ShowErrorAsync("请先选择要删除的配方");
				return;
			}

			if (SelectedExperimentGroup == null)
			{
				await _messageService.ShowErrorAsync("请先选择实验组");
				return;
			}

			try
			{
				var confirm = await _messageService.ShowConfirmAsync(
					$"确定要从实验组 {SelectedExperimentGroup.GroupName} 中移除配方 {recipe.ExperimentName} 吗？",
					"删除确认");

				if (!confirm) return;

				IsLoading = true;

				// 保存当前实验组的ID和引用
				var currentGroupId = SelectedExperimentGroup.GroupId;
				var currentGroup = SelectedExperimentGroup;

				// 从配方集合中移除配方
				currentGroup.Recipes.Remove(recipe);

				// 从实验集合中移除对应的实验
				var experimentsToRemove = currentGroup.Experiments
					.Where(e => e.RecipeId == recipe.RecipeId)
					.ToList();

				foreach (var experiment in experimentsToRemove)
				{
					currentGroup.Experiments.Remove(experiment);
				}

				// 更新实验组
				var result = await _recipeAppService.UpdateExperimentGroupAsync(currentGroup);

				if (!result.Success)
				{
					// 如果更新失败，恢复配方
					currentGroup.Recipes.Add(recipe);

					// 重新创建实验
					currentGroup.CreateExperimentsFromRecipes();

					_logger.LogWarning($"从实验组移除配方失败: {result.Message}");
					await _messageService.ShowErrorAsync($"移除失败: {result.Message}");
				}
				else
				{
					_logger.LogInformation($"从实验组 {currentGroup.GroupName} 中移除配方 {recipe.ExperimentName} 成功");
					await _messageService.ShowInfoAsync("配方已从实验组中移除");

					// 重新加载实验组列表以更新UI
					await LoadExperimentGroupsAsync();

					// 重新选择当前实验组
					SelectedExperimentGroup = ExperimentGroups.FirstOrDefault(g => g.GroupId == currentGroupId);
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"从实验组移除配方时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"移除失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 加载实验组列表
		/// </summary>
		private async Task LoadExperimentGroupsAsync()
		{
			try
			{
				var groups = await _recipeAppService.GetAllExperimentGroupsAsync();
				ExperimentGroups.Clear();
				foreach (var group in groups)
				{
					ExperimentGroups.Add(group);
				}
				_logger.LogInformation($"成功加载 {groups.Count()} 个实验组");
			}
			catch (Exception ex)
			{
				_logger.LogError($"加载实验组失败: {ex.Message}");
				await _messageService.ShowErrorAsync($"加载实验组失败: {ex.Message}");
				ExperimentGroups.Clear();
			}
		}

		/// <summary>
		/// 创建新实验组命令
		/// </summary>
		[RelayCommand]
		private async Task CreateExperimentGroupAsync()
		{
			try
			{
				IsLoading = true;
				var newGroup = new ExperimentGroup
				{
					GroupId = Guid.NewGuid(),
					GroupName = $"新建实验组_{DateTime.Now:yyyyMMdd_HHmmss}",
					CreatedTime = DateTime.Now,
					Creator = "当前用户",
					Description = "新建实验组",
					Recipes = new ObservableCollection<RecipeDefinition>(),
					Experiments = new ObservableCollection<Experiment>(),
					Status = ExperimentGroupStatus.Pending,
					ErrorMessage = string.Empty,
					ExecutionProgress = 0,
					Executor = "当前用户"
				};

				var result = await _recipeAppService.CreateExperimentGroupAsync(newGroup);
				if (result.Success)
				{
					_logger.LogInformation($"实验组 {newGroup.GroupName} 创建成功");
					await _messageService.ShowInfoAsync("实验组创建成功");
					await LoadExperimentGroupsAsync();
					SelectedExperimentGroup = ExperimentGroups.FirstOrDefault(g => g.GroupId == result.GroupId);
				}
				else
				{
					_logger.LogWarning($"创建实验组失败: {result.Message}");
					await _messageService.ShowErrorAsync($"创建失败: {result.Message}");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"创建实验组时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"创建失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 删除实验组命令
		/// </summary>
		[RelayCommand]
		private async Task DeleteExperimentGroupAsync(ExperimentGroup group)
		{
			if (group == null) return;

			try
			{
				var confirm = await _messageService.ShowConfirmAsync($"确定要删除实验组 {group.GroupName} 吗？", "删除确认");
				if (!confirm) return;

				IsLoading = true;
				var result = await _recipeAppService.DeleteExperimentGroupAsync(group.GroupId);

				if (result.Success)
				{
					_logger.LogInformation($"实验组 {group.GroupName} 删除成功");
					await _messageService.ShowInfoAsync("实验组删除成功");
					await LoadExperimentGroupsAsync();
					SelectedExperimentGroup = null;
				}
				else
				{
					_logger.LogWarning($"删除实验组失败: {result.Message}");
					await _messageService.ShowErrorAsync($"删除失败: {result.Message}");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"删除实验组时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"删除失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 更新实验组命令
		/// </summary>
		[RelayCommand]
		private async Task UpdateExperimentGroupAsync(ExperimentGroup group)
		{
			if (group == null) return;

			try
			{
				IsLoading = true;

				// 确保实验列表与配方列表同步
				group.CreateExperimentsFromRecipes();

				var result = await _recipeAppService.UpdateExperimentGroupAsync(group);
				if (result.Success)
				{
					_logger.LogInformation($"实验组 {group.GroupName} 更新成功");
					await _messageService.ShowInfoAsync("实验组更新成功");
					await LoadExperimentGroupsAsync();
					SelectedExperimentGroup = ExperimentGroups.FirstOrDefault(g => g.GroupId == group.GroupId);
				}
				else
				{
					_logger.LogWarning($"更新实验组失败: {result.Message}");
					await _messageService.ShowErrorAsync($"更新失败: {result.Message}");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"更新实验组时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"更新失败: {ex.Message}");
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 从实验组中选择配方进行编辑
		/// </summary>
		[RelayCommand]
		private async Task LoadRecipeToEditorAsync(RecipeDefinition recipe)
		{
			if (recipe == null) return;

			try
			{
				var confirm = await _messageService.ShowConfirmAsync(
					"加载此配方到编辑区域将覆盖当前编辑的内容，是否继续？",
					"确认加载");

				if (!confirm) return;

				// 创建配方的深拷贝
				EditingRecipe = new RecipeDefinition
				{
					ExperimentName = recipe.ExperimentName,
					ExperimentDescription = recipe.ExperimentDescription,
					CreatedTime = DateTime.Now, // 新建时间
					Operator = recipe.Operator,
					ExperimentType = recipe.ExperimentType,
					RotovapParameters = recipe.RotovapParameters?.Clone() ?? new RotovapParameters
					{
						ProductParameters = new ObservableCollection<ProductParameters>(),
						MaterialLocations = new ObservableCollection<int>(),
						ResidualLiquidParameters = new ResidualLiquidParameters(),
						CleaningParameters = new CleaningParameters()
					}
				};

				_logger.LogInformation($"已加载配方 {recipe.ExperimentName} 到编辑区");
				await _messageService.ShowInfoAsync($"已加载配方 {recipe.ExperimentName} 到编辑区");
			}
			catch (Exception ex)
			{
				_logger.LogError($"加载配方到编辑区时发生错误: {ex.Message}");
				await _messageService.ShowErrorAsync($"加载配方失败: {ex.Message}");
			}
		}

		/// <summary>
		/// 刷新物料和清洗液数据命令
		/// </summary>
		[RelayCommand]
		public async Task RefreshMaterialsAndSolutionsAsync()
		{
			try
			{
				IsLoading = true;
				await LoadMaterialsAndSolutionsAsync();

				// 如果有正在编辑的配方，更新匹配的瓶子位置
				if (EditingRecipe?.RotovapParameters != null && !string.IsNullOrEmpty(EditingRecipe.RotovapParameters.MaterialName))
				{
					await UpdateMatchedBottleLocationsAsync();
				}

				await _messageService.ShowInfoAsync("物料和清洗液数据已刷新", "刷新成功");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "刷新物料和清洗液数据失败");
				await _messageService.ShowErrorAsync("刷新失败", ex.Message);
			}
			finally
			{
				IsLoading = false;
			}
		}

		/// <summary>
		/// 当物料名称变化时调用此方法
		/// </summary>
		public async Task OnMaterialNameChangedAsync()
		{
			if (EditingRecipe?.RotovapParameters != null)
			{
				_logger.LogInformation($"物料名称已变更为: {EditingRecipe.RotovapParameters.MaterialName}");
				await UpdateMatchedBottleLocationsAsync();
			}
		}

		/// <summary>
		/// 当冷凝器清洗液变化时调用此方法
		/// </summary>
		public void OnCondensationCleaningSolutionChanged()
		{
			if (EditingRecipe?.RotovapParameters?.CleaningParameters != null)
			{
				_logger.LogInformation($"冷凝器清洗液已变更为: {EditingRecipe.RotovapParameters.CleaningParameters.CondensationCleaningSolution}");
			}
		}

		/// <summary>
		/// 当旋蒸瓶清洗液变化时调用此方法
		/// </summary>
		public void OnRotaryBottleCleaningSolutionChanged()
		{
			if (EditingRecipe?.RotovapParameters?.CleaningParameters != null)
			{
				_logger.LogInformation($"旋蒸瓶清洗液已变更为: {EditingRecipe.RotovapParameters.CleaningParameters.RotaryBottleCleaningSolution}");
			}
		}

		#endregion

		#region 公共方法

		/// <summary>
		/// 初始化视图模型
		/// </summary>
		public async Task InitializeAsync()
		{
			try
			{
				// 确保在UI线程执行数据绑定
				await System.Windows.Application.Current.Dispatcher.InvokeAsync(async () =>
				{
					IsLoading = true;
					_logger.LogInformation("开始初始化RecipeEditorViewModel");

					// 只在第一次初始化时加载配方和实验组
					if (!_isInitialized)
					{
						await LoadRecipesAsync();
						await LoadExperimentGroupsAsync();

						// 初始化参数范围
						await InitializeParameterRangesAsync();

						_isInitialized = true;
					}

					// 每次都重新加载物料和清洗液数据
					_logger.LogInformation("初始化时加载物料和清洗液数据");
					await LoadMaterialsAndSolutionsAsync();

					// 如果有正在编辑的配方，更新匹配的瓶子位置
					if (EditingRecipe?.RotovapParameters != null && !string.IsNullOrEmpty(EditingRecipe.RotovapParameters.MaterialName))
					{
						_logger.LogInformation($"初始化时更新匹配瓶子位置，当前物料名称: {EditingRecipe.RotovapParameters.MaterialName}");
						await UpdateMatchedBottleLocationsAsync();
					}

					IsLoading = false;
					_logger.LogInformation("RecipeEditorViewModel初始化完成");
				});
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "初始化RecipeEditorViewModel时发生错误");
				await _messageService.ShowErrorAsync("初始化失败", ex.Message);
				IsLoading = false;
			}
		}

		/// <summary>
		/// 初始化参数范围
		/// </summary>
		private async Task InitializeParameterRangesAsync()
		{
			try
			{
				_logger.LogInformation("开始初始化参数范围");

				// 初始化参数范围服务
				await _deviceParameterService.InitializeAsync();

				// 获取油浴温度范围
				var oilTemperatureRange = await _deviceParameterService.GetOilTemperatureRangeAsync();
				OilTemperatureMin = oilTemperatureRange.Min;
				OilTemperatureMax = oilTemperatureRange.Max;
				OilTemperatureUnit = oilTemperatureRange.Unit;

				// 获取旋蒸转速范围
				var rotarySpeedRange = await _deviceParameterService.GetRotarySpeedRangeAsync();
				RotarySpeedMin = rotarySpeedRange.Min;
				RotarySpeedMax = rotarySpeedRange.Max;
				RotarySpeedUnit = rotarySpeedRange.Unit;

				// 获取阶梯温度范围
				var stepTemperatureRange = await _deviceParameterService.GetStepTemperatureRangeAsync();
				StepTemperatureMin = stepTemperatureRange.Min;
				StepTemperatureMax = stepTemperatureRange.Max;
				StepTemperatureUnit = stepTemperatureRange.Unit;

				// 获取阶梯稳定时间范围
				var stepStableTimeRange = await _deviceParameterService.GetStepStableTimeRangeAsync();
				StepStableTimeMin = stepStableTimeRange.Min;
				StepStableTimeMax = stepStableTimeRange.Max;
				StepStableTimeUnit = stepStableTimeRange.Unit;

				// 获取旋蒸时间范围
				var rotaryTimeRange = await _deviceParameterService.GetRotaryTimeRangeAsync();
				RotaryTimeMin = rotaryTimeRange.Min;
				RotaryTimeMax = rotaryTimeRange.Max;
				RotaryTimeUnit = rotaryTimeRange.Unit;

				// 获取冷凝温度范围
				var condensationTemperatureRange = await _deviceParameterService.GetCondensationTemperatureRangeAsync();
				CondensationTemperatureMin = condensationTemperatureRange.Min;
				CondensationTemperatureMax = condensationTemperatureRange.Max;
				CondensationTemperatureUnit = condensationTemperatureRange.Unit;

				// 获取真空度范围
				var vacuumRange = await _deviceParameterService.GetVacuumRangeAsync();
				VacuumMin = vacuumRange.Min;
				VacuumMax = vacuumRange.Max;
				VacuumUnit = vacuumRange.Unit;

				// 获取清洗体积范围
				var cleaningVolumeRange = await _deviceParameterService.GetCleaningVolumeRangeAsync();
				CleaningVolumeMin = cleaningVolumeRange.Min;
				CleaningVolumeMax = cleaningVolumeRange.Max;
				CleaningVolumeUnit = cleaningVolumeRange.Unit;

				// 获取清洗速度范围
				var cleaningSpeedRange = await _deviceParameterService.GetCleaningSpeedRangeAsync();
				CleaningSpeedMin = cleaningSpeedRange.Min;
				CleaningSpeedMax = cleaningSpeedRange.Max;
				CleaningSpeedUnit = cleaningSpeedRange.Unit;

				// 获取清洗时间范围
				var cleaningTimeRange = await _deviceParameterService.GetCleaningTimeRangeAsync();
				CleaningTimeMin = cleaningTimeRange.Min;
				CleaningTimeMax = cleaningTimeRange.Max;
				CleaningTimeUnit = cleaningTimeRange.Unit;

				_logger.LogInformation("参数范围初始化完成");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "初始化参数范围失败");

				// 设置默认范围
				OilTemperatureMin = 0;
				OilTemperatureMax = 100;
				OilTemperatureUnit = "℃";

				RotarySpeedMin = 0;
				RotarySpeedMax = 200;
				RotarySpeedUnit = "rpm";

				StepTemperatureMin = 0;
				StepTemperatureMax = 100;
				StepTemperatureUnit = "℃";

				StepStableTimeMin = 0;
				StepStableTimeMax = 60;
				StepStableTimeUnit = "min";

				RotaryTimeMin = 0;
				RotaryTimeMax = 120;
				RotaryTimeUnit = "min";

				CondensationTemperatureMin = -20;
				CondensationTemperatureMax = 30;
				CondensationTemperatureUnit = "℃";

				VacuumMin = 0;
				VacuumMax = 1;
				VacuumUnit = "";

				CleaningVolumeMin = 0;
				CleaningVolumeMax = 500;
				CleaningVolumeUnit = "ml";

				CleaningSpeedMin = 0;
				CleaningSpeedMax = 50;
				CleaningSpeedUnit = "ml/min";

				CleaningTimeMin = 0;
				CleaningTimeMax = 30;
				CleaningTimeUnit = "min";
			}
		}

		#endregion

		#region 私有方法

		/// <summary>
		/// 加载配方列表
		/// </summary>
		private async Task LoadRecipesAsync()
		{
			try
			{
				_isUserSelection = false; // 暂时禁用自动更新编辑区
				var recipes = await _recipeAppService.GetAllRecipesAsync();
				Recipes = new ObservableCollection<RecipeDefinition>(recipes);
				UpdatePagedRecipes();
				_logger.LogInformation($"成功加载 {recipes.Count()} 个配方");
			}
			catch (Exception ex)
			{
				_logger.LogError($"加载配方失败: {ex.Message}");
				await _messageService.ShowErrorAsync($"加载配方失败: {ex.Message}");
				Recipes = new ObservableCollection<RecipeDefinition>();
			}
			finally
			{
				_isUserSelection = true; // 恢复自动更新编辑区
			}
		}

		/// <summary>
		/// 更新分页显示的配方列表
		/// </summary>
		private void UpdatePagedRecipes()
		{
			try
			{
				// 创建一个本地列表用于查询
				var recipesList = Recipes.ToList();
				IEnumerable<RecipeDefinition> query = recipesList;

				// 应用搜索过滤
				if (!string.IsNullOrWhiteSpace(SearchText))
				{
					query = recipesList.Where(r =>
						(r.ExperimentName?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) == true) ||
						(r.RotovapParameters?.MaterialName?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) == true) ||
						(r.ExperimentDescription?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) == true) ||
						(r.Operator?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) == true)
					);
				}

				// 计算总页数
				var totalItems = query.Count();
				TotalPages = Math.Max(1, (int)Math.Ceiling(totalItems / (double)SelectedPageSize));

				// 确保当前页码有效
				CurrentPage = Math.Max(1, Math.Min(CurrentPage, TotalPages));

				// 计算分页
				var skip = (CurrentPage - 1) * SelectedPageSize;
				var pagedRecipes = query.Skip(skip).Take(SelectedPageSize).ToList();

				// 更新UI
				PagedRecipes.Clear();
				foreach (var recipe in pagedRecipes)
				{
					PagedRecipes.Add(recipe);
				}

				// 更新命令状态
				UpdatePaginationCommands();
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.WriteLine($"更新分页数据时出错: {ex.Message}");
				// 确保至少显示空列表
				PagedRecipes.Clear();
				TotalPages = 1;
				CurrentPage = 1;
			}
		}

		/// <summary>
		/// 更新分页命令的可用状态
		/// </summary>
		private void UpdatePaginationCommands()
		{
			PreviousPageCommand.NotifyCanExecuteChanged();
			NextPageCommand.NotifyCanExecuteChanged();
		}

		/// <summary>
		/// 检查是否可以跳转到上一页
		/// </summary>
		private bool CanGoToPreviousPage => CurrentPage > 1;

		/// <summary>
		/// 检查是否可以跳转到下一页
		/// </summary>
		private bool CanGoToNextPage => CurrentPage < _totalPages;

		/// <summary>
		/// 初始化编辑中的配方
		/// </summary>
		private void InitializeEditingRecipe()
		{
			_logger.LogDebug("开始初始化新配方");

			EditingRecipe = new RecipeDefinition
			{
				RotovapParameters = new RotovapParameters
				{
					ProductParameters = new ObservableCollection<ProductParameters>(),
					MaterialLocations = new ObservableCollection<int>(),
					ResidualLiquidParameters = new ResidualLiquidParameters(),
					CleaningParameters = new CleaningParameters()
				}
			};

			_logger.LogDebug($"新配方初始化完成，ExperimentName: {EditingRecipe.ExperimentName}");
		}

		partial void OnSelectedExperimentGroupChanged(ExperimentGroup value)
		{
			if (value != null)
			{
				DisplayGroupName = value.GroupName;
			}
			else
			{
				DisplayGroupName = NewGroupName;
			}
		}

		partial void OnDisplayGroupNameChanged(string value)
		{
			if (SelectedExperimentGroup != null)
			{
				SelectedExperimentGroup.GroupName = value;
			}
			else
			{
				NewGroupName = value;
			}
		}

		/// <summary>
		/// 加载物料和清洗液数据
		/// </summary>
		private async Task LoadMaterialsAndSolutionsAsync()
		{
			try
			{
				_logger.LogInformation("开始加载物料和清洗液数据");

				// 确保在UI线程上执行集合更新
				await System.Windows.Application.Current.Dispatcher.InvokeAsync(() => {
					// 清空现有数据
					AvailableRotovapMaterials.Clear();
					AvailableCleaningSolutions.Clear();
				});

				// 获取所有货架位置
				var allLocations = await _storageAppService.GetAllShelfLocationsAsync();
				_logger.LogInformation($"获取到 {allLocations.Count} 个货架位置");

				// 记录每个位置的详细信息，用于调试
				foreach (var loc in allLocations)
				{
					_logger.LogDebug($"位置: {loc.LocationCode}-{loc.Position}, 是否有物品: {loc.IsOccupied}, CurrentItem: {(loc.CurrentItem != null ? "有" : "无")}");
					if (loc.CurrentItem != null)
					{
						_logger.LogDebug($"  物品类型: {loc.CurrentItem.GetType().Name}");
						if (loc.CurrentItem is CentrifugeBottle bottle)
						{
							_logger.LogDebug($"  离心瓶信息 - 功能: {bottle.Function}, 物料名称: {bottle.MaterialName}, 当前体积: {bottle.CurrentVolume}");
						}
					}
				}

				// 筛选出500ml离心瓶且功能分类为待旋蒸液的物料
				var rotovapMaterials = allLocations
					.Where(loc => loc.CurrentItem != null &&
						   loc.CurrentItem is CentrifugeBottle bottle &&
						   bottle.Function == FunctionType.Centrifuge_To_Rotovap)
					.Select(loc => ((CentrifugeBottle)loc.CurrentItem).MaterialName)
					.Distinct()
					.OrderBy(name => name)
					.ToList();

				_logger.LogInformation($"找到 {rotovapMaterials.Count} 个待旋蒸物料");

				// 记录找到的物料名称
				foreach (var material in rotovapMaterials)
				{
					_logger.LogDebug($"待旋蒸物料: {material}");
				}

				// 筛选出500ml离心瓶且功能分类为洗液的物料
				var cleaningSolutions = allLocations
					.Where(loc => loc.CurrentItem != null &&
						   loc.CurrentItem is CentrifugeBottle bottle &&
						   bottle.Function == FunctionType.Centrifuge_Wash_Liquid)
					.Select(loc => ((CentrifugeBottle)loc.CurrentItem).MaterialName)
					.Distinct()
					.OrderBy(name => name)
					.ToList();

				_logger.LogInformation($"找到 {cleaningSolutions.Count} 个清洗液");

				// 记录找到的清洗液名称
				foreach (var solution in cleaningSolutions)
				{
					_logger.LogDebug($"清洗液: {solution}");
				}

				// 在UI线程上更新集合
				await System.Windows.Application.Current.Dispatcher.InvokeAsync(() => {
					// 添加到可用物料列表
					foreach (var material in rotovapMaterials)
					{
						AvailableRotovapMaterials.Add(material);
					}

					// 如果没有找到待旋蒸物料，添加一些默认值用于测试
					if (AvailableRotovapMaterials.Count == 0)
					{
						_logger.LogWarning("未找到待旋蒸物料，添加默认测试值");
						AvailableRotovapMaterials.Add("测试物料1");
						AvailableRotovapMaterials.Add("测试物料2");
						AvailableRotovapMaterials.Add("测试物料3");
					}

					// 添加到可用清洗液列表
					foreach (var solution in cleaningSolutions)
					{
						AvailableCleaningSolutions.Add(solution);
					}

					// 如果没有找到清洗液，添加一些默认值用于测试
					if (AvailableCleaningSolutions.Count == 0)
					{
						_logger.LogWarning("未找到清洗液，添加默认测试值");
						AvailableCleaningSolutions.Add("测试清洗液1");
						AvailableCleaningSolutions.Add("测试清洗液2");
					}

					// 触发属性变更通知，确保UI更新
					OnPropertyChanged(nameof(AvailableRotovapMaterials));
					OnPropertyChanged(nameof(AvailableCleaningSolutions));
				});

				_logger.LogInformation("物料和清洗液数据加载完成");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "加载物料和清洗液数据失败");
				await _messageService.ShowErrorAsync("加载物料数据失败", ex.Message);

				// 确保即使出错也添加一些默认值
				await System.Windows.Application.Current.Dispatcher.InvokeAsync(() => {
					if (AvailableRotovapMaterials.Count == 0)
					{
						AvailableRotovapMaterials.Add("测试物料1");
						AvailableRotovapMaterials.Add("测试物料2");
						AvailableRotovapMaterials.Add("测试物料3");
					}

					if (AvailableCleaningSolutions.Count == 0)
					{
						AvailableCleaningSolutions.Add("测试清洗液1");
						AvailableCleaningSolutions.Add("测试清洗液2");
					}
				});
			}
		}

		/// <summary>
		/// 更新匹配当前选择物料的瓶子位置
		/// </summary>
		private async Task UpdateMatchedBottleLocationsAsync()
		{
			try
			{
				_logger.LogInformation("开始更新匹配瓶子位置");

				// 清空现有数据
				MatchedBottleLocations.Clear();

				// 如果没有选择物料，则返回
				if (EditingRecipe?.RotovapParameters == null ||
					string.IsNullOrEmpty(EditingRecipe.RotovapParameters.MaterialName))
				{
					_logger.LogInformation("未选择物料，不更新匹配瓶子位置");
					return;
				}

				_logger.LogInformation($"当前选择的物料名称: {EditingRecipe.RotovapParameters.MaterialName}");

				// 获取所有货架位置
				var allLocations = await _storageAppService.GetAllShelfLocationsAsync();
				_logger.LogInformation($"获取到 {allLocations.Count} 个货架位置");

				// 筛选出匹配当前物料名称的位置
				var matchedLocations = allLocations
					.Where(loc => loc.CurrentItem != null &&
						   loc.CurrentItem is CentrifugeBottle bottle &&
						   bottle.MaterialName == EditingRecipe.RotovapParameters.MaterialName)
					.ToList();

				_logger.LogInformation($"找到 {matchedLocations.Count} 个匹配的瓶子位置");

				// 更新MaterialLocations集合
				var positions = matchedLocations
					.Select(loc => loc.Position)
					.ToList();

				// 创建新的ObservableCollection并赋值
				EditingRecipe.RotovapParameters.MaterialLocations = new ObservableCollection<int>(positions);

				_logger.LogInformation($"已更新MaterialLocations集合，共 {EditingRecipe.RotovapParameters.MaterialLocations.Count} 个位置");

				// 添加到匹配位置列表
				foreach (var location in matchedLocations)
				{
					MatchedBottleLocations.Add(new BottleLocationViewModel
					{
						Position = location.Position,
						DisplayName = $"位置: {_storageAppService.GetShelfDisplayName(location.Position)}"
					});
				}

				_logger.LogInformation("匹配瓶子位置更新完成");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "更新匹配瓶子位置失败");
				await _messageService.ShowErrorAsync("更新瓶子位置失败", ex.Message);
			}
		}

		/// <summary>
		/// 处理编辑配方变更事件
		/// </summary>
		private async void OnEditingRecipeChanged(RecipeDefinition recipe)
		{
			if (recipe == null)
			{
				_logger.LogWarning("EditingRecipe 被设置为 null");
				return;
			}

			_logger.LogInformation($"EditingRecipe 已更改，ExperimentName: {recipe.ExperimentName}");

			// 确保 RotovapParameters 不为空
			if (recipe.RotovapParameters == null)
			{
				_logger.LogInformation("初始化 RotovapParameters");
				recipe.RotovapParameters = new RotovapParameters
				{
					ProductParameters = new ObservableCollection<ProductParameters>(),
					MaterialLocations = new ObservableCollection<int>(),
					ResidualLiquidParameters = new ResidualLiquidParameters(),
					CleaningParameters = new CleaningParameters()
				};
			}

			// 确保 ProductParameters 不为空
			if (recipe.RotovapParameters.ProductParameters == null)
			{
				_logger.LogInformation("初始化 ProductParameters 集合");
				recipe.RotovapParameters.ProductParameters = new ObservableCollection<ProductParameters>();
			}

			// 确保 MaterialLocations 不为空
			if (recipe.RotovapParameters.MaterialLocations == null)
			{
				_logger.LogInformation("初始化 MaterialLocations 集合");
				recipe.RotovapParameters.MaterialLocations = new ObservableCollection<int>();
			}

			// 确保 ResidualLiquidParameters 不为空
			if (recipe.RotovapParameters.ResidualLiquidParameters == null)
			{
				_logger.LogInformation("初始化 ResidualLiquidParameters");
				recipe.RotovapParameters.ResidualLiquidParameters = new ResidualLiquidParameters();
			}

			// 确保 CleaningParameters 不为空
			if (recipe.RotovapParameters.CleaningParameters == null)
			{
				_logger.LogInformation("初始化 CleaningParameters");
				recipe.RotovapParameters.CleaningParameters = new CleaningParameters();
			}

			// 如果有物料名称，更新匹配的瓶子位置
			if (!string.IsNullOrEmpty(recipe.RotovapParameters.MaterialName))
			{
				_logger.LogInformation($"更新匹配瓶子位置，当前物料名称: {recipe.RotovapParameters.MaterialName}");
				await UpdateMatchedBottleLocationsAsync();
			}

			// 记录产物参数信息
			if (recipe.RotovapParameters.ProductParameters.Count > 0)
			{
				foreach (var param in recipe.RotovapParameters.ProductParameters)
				{
					_logger.LogDebug($"产物参数：油浴温度={param.OilTemperature}, 转速={param.RotarySpeed}, 时间={param.RotaryTime}");
				}
			}

			// 通知 UI 更新
			OnPropertyChanged(nameof(CanAddProductParameters));
		}

		#endregion
	}

	/// <summary>
	/// 瓶子位置视图模型
	/// </summary>
	public class BottleLocationViewModel
	{
		public int Position { get; set; }
		public string DisplayName { get; set; }
	}
}

